<?php
require("./world/model/Player.class.php");
require("./world/model/NPC.class.php");
require("./world/model/managers/NPCManager.class.php");

/**
 * Represents a Single World.
 *
 * @author Mark Dohmen.
 */
final class World {
	
	/**
	 * The world id.
	 */
	private $worldId;
	
	/**
 	 * Instance of World.
 	 */
	private static $world;
	
	/**
 	 * List of all NPC's in this world.
 	 */
	private $npcList;
	
	/**
 	 * List of all Players in this world.
 	 */
	private $playerList;
	
	/**
	 * List of all objects in this world.
	 */
	private $objectList;
	
	/**
 	 * Instance of NPCManager.
 	 */
	private $npcManager;
	
	/**
	 * Instance of ObjectManager.
	 */
	private $objectManager;
	
	/**
	 * Istance of ItemManager.
	 */
	private $itemManager;
	
	/**
 	 * Class Constructor.
 	 */
	final public function World(int $worldId) {
		$this->worldId = $worldId;
		$this->npcManager = new NPCManager();
		$this->npcManager->load();
		$this->objectManager = new ObjectManager();
		$this->objectManager->load();
		$this->itemManager = new ItemManager();
		$this->itemManager->load();
		WorldLoader::getWorldLoader()->loadPlayers();
	}
	
	/**
	 * Initialize the world.
	 *
	 * @param $worldId
	 */
	final public static function init(int $worldId) {
		self::$world = new World($worldId);	
	}
	
	/**
 	 * Register a Player to this world.
	 *
	 * @param $player
 	 */
	final public function registerPlayer(Player $player) {
		for ($i = 0; $i < count($this->playerList); $i++) {
			if ($this->playerList[$i] === $player) {
				return "You are allready logged in!";
			}
		}
		$this->playerList[] = $player;
	}
	
	/**
 	 * Un register a Player from this world.
	 *
	 * @param $player
 	 */
	final public function unRegisterPlayer(Player $player) {
		for ($i = 0; $i < count($this->playerList); $i++) {
			if ($this->playerList[$i]->getId() == $player->getId()) {
				unset($this->playerList[$i]);
			}
		}
	}
	
	/**
 	 * Register an NPC to this world.
	 *
	 * @param $npc
 	 */
	final public function registerNPC(NPC $npc) {
		$this->npcList[] = $npc;
	}
	
	/**
 	 * Un register an NPC from this world.
	 *
	 * @param $npc
 	 */
	final public function unRegisterNPC(NPC $npc) {
		for ($i = 0; $i < count($this->npcList); $i++) {
			if ($this->npcList[$i]->getId() == $npc->getId()) {
				unset($this->npcList[$i]);
			}
		}
	}
	
	/**
 	 * Register an Object to this world.
	 *
	 * @param $object
 	 */
	final public function registerObject(Object $object) {
		$this->objectList[] = $object;
	}
	
	/**
 	 * Un register an Object from this world.
	 *
	 * @param $object
 	 */
	final public function unRegisterObject(Object $object) {
		for ($i = 0; $i < count($this->objectList); $i++) {
			if ($this->objectList[$i]->getDefinition()->getId() == $object->getDefinition()->getId()) {
				unset($this->objectList[$i]);
			}
		}
	}
	
	/**
	 * Gets the world id.
	 *
	 * @return $id
	 */
	final public function getWorldId() {
		return (int) $this->worldId;	
	}
	
	/**
 	 * Gets the instance of World.
	 *
	 * @return $world
 	 */
	final public function getWorld() {
		if (self::$world instanceof World) {
			return (object) self::$world;
		}
	}
	
	/**
 	 * Gets the list of players.
	 *
	 * @return $playerList
 	 */
	final public function getPlayerList() {
		return (array) $this->playerList;	
	}
	
	/**
 	 * Gets the list of NPC's
	 *
	 * @return $npcList
 	 */
	final public function getNPCList() {
		return (array) $this->npcList;	
	}
	
	/**
 	 * Gets the list of Objects
	 *
	 * @return $objectList
 	 */
	final public function getObjectList() {
		return (array) $this->objectList;	
	}
	
	/**
	 * Returns the NPC Manager for this world.
	 *
	 * @return $npcManager/null
	 */
	final public function getNPCManager() {
		if ($this->npcManager instanceof NPCManager) {
			return (object) $this->npcManager;
		}
		return NULL;
	}
	
	/**
	 * Returns the Object Manager for this world.
	 *
	 * @return $objectManager/null
	 */
	final public function getObjectManager() {
		if ($this->objectManager instanceof ObjectManager) {
			return (object) $this->objectManager;
		}
		return NULL;
	}
	
	/**
	 * Returns the Item Manager for this world.
	 *
	 * @return $itemManager/null
	 */
	final public function getItemManager() {
		if ($this->itemManager instanceof ItemManager) {
			return (object) $this->itemManager;
		}
		return NULL;
	}
}
?>